fix(agentx): rerun DeepSeek-V4 B300 SGLang with OOM headroom / 修复 AgentX:为 DeepSeek-V4 B300 SGLang 重跑预留 OOM 余量#2226
fix(agentx): rerun DeepSeek-V4 B300 SGLang with OOM headroom / 修复 AgentX:为 DeepSeek-V4 B300 SGLang 重跑预留 OOM 余量#2226cquil11 wants to merge 2 commits into
Conversation
Carry the B300-only SGLang AgentX recipe and search-space changes from PR #2145 onto current main. Reduce DEP4 mem-fraction-static from 0.93 to 0.90 after run 29367944489 showed sparse-attention indexer CUDA OOMs during warmup.\n\n中文:将原 PR #2145 中仅适用于 B300 的 SGLang AgentX 配方与搜索空间变更迁移到最新 main。根据运行 29367944489 在预热阶段出现的稀疏注意力索引器 CUDA OOM,将 DEP4 的 mem-fraction-static 从 0.93 降至 0.90,为激活值和工作区预留更多 HBM。
|
Thanks for the contribution! Please reach out to respective companies' CODEOWNER to fill in the latest PR_REVIEW_CHECKLIST.md before pinging core maintainer on Slack for review. In order for the signoff PR check bot to trigger, you must follow the PR_REVIEW_CHECKLIST.md template correctly, including the phrase For PR verification, add the PR authors are responsible for ensuring that after merging, all GitHub Action jobs fully pass. A lot of the time, failures are just flakes and simply re-running the failed jobs will fix it. See GitHub's docs on re-running failed jobs 感谢你的贡献!请联系相应公司的 CODEOWNER 填写最新的 PR_REVIEW_CHECKLIST.md,然后再在 Slack 上联系核心维护者进行审阅。为了触发 signoff PR 检查机器人,你必须正确遵循 PR_REVIEW_CHECKLIST.md 模板,包括保留英文语句 如需进行 PR 验证,请为此 PR 添加 PR 作者有责任确保合并后所有 GitHub Action 任务完全通过。 很多时候失败只是偶发抖动(flake),重新运行失败的任务即可解决。参见 GitHub 关于重新运行失败任务的文档 |
2 similar comments
|
Thanks for the contribution! Please reach out to respective companies' CODEOWNER to fill in the latest PR_REVIEW_CHECKLIST.md before pinging core maintainer on Slack for review. In order for the signoff PR check bot to trigger, you must follow the PR_REVIEW_CHECKLIST.md template correctly, including the phrase For PR verification, add the PR authors are responsible for ensuring that after merging, all GitHub Action jobs fully pass. A lot of the time, failures are just flakes and simply re-running the failed jobs will fix it. See GitHub's docs on re-running failed jobs 感谢你的贡献!请联系相应公司的 CODEOWNER 填写最新的 PR_REVIEW_CHECKLIST.md,然后再在 Slack 上联系核心维护者进行审阅。为了触发 signoff PR 检查机器人,你必须正确遵循 PR_REVIEW_CHECKLIST.md 模板,包括保留英文语句 如需进行 PR 验证,请为此 PR 添加 PR 作者有责任确保合并后所有 GitHub Action 任务完全通过。 很多时候失败只是偶发抖动(flake),重新运行失败的任务即可解决。参见 GitHub 关于重新运行失败任务的文档 |
|
Thanks for the contribution! Please reach out to respective companies' CODEOWNER to fill in the latest PR_REVIEW_CHECKLIST.md before pinging core maintainer on Slack for review. In order for the signoff PR check bot to trigger, you must follow the PR_REVIEW_CHECKLIST.md template correctly, including the phrase For PR verification, add the PR authors are responsible for ensuring that after merging, all GitHub Action jobs fully pass. A lot of the time, failures are just flakes and simply re-running the failed jobs will fix it. See GitHub's docs on re-running failed jobs 感谢你的贡献!请联系相应公司的 CODEOWNER 填写最新的 PR_REVIEW_CHECKLIST.md,然后再在 Slack 上联系核心维护者进行审阅。为了触发 signoff PR 检查机器人,你必须正确遵循 PR_REVIEW_CHECKLIST.md 模板,包括保留英文语句 如需进行 PR 验证,请为此 PR 添加 PR 作者有责任确保合并后所有 GitHub Action 任务完全通过。 很多时候失败只是偶发抖动(flake),重新运行失败的任务即可解决。参见 GitHub 关于重新运行失败任务的文档 |
| MEM_FRACTION_STATIC=0.85 | ||
| SWA_FULL_TOKENS_RATIO=0.075 | ||
| # MegaMoE requires the default (non-compressed) attention path and fused shared experts. | ||
| MODEL_ARGS=() | ||
| EXTRA_ARGS=(--enable-prefill-delayer) | ||
| # chunked-prefill is divided by dp_size (=TP) under DP-attention; keep the | ||
| # effective chunk at 8192. Size the decode graph to served concurrency: | ||
| # DEP8 (dp 8) serves conc up to 512, DEP4 (dp 4) tops out near 128. | ||
| if [ "$TP" = "8" ]; then | ||
| CHUNKED_PREFILL_SIZE=65536 | ||
| CUDA_GRAPH_ARGS=(--cuda-graph-max-bs-decode 544) | ||
| else | ||
| # DEP4 (TP4/EP4) shards the model across only 4 GPUs, so per-GPU weights | ||
| # are ~2x DEP8 (233 GB loaded; profiler floor ~0.879). At 0.93, run | ||
| # 29367944489 left only 2.9-4.8 GiB free while the sparse-attention | ||
| # indexer requested 4.2-6.1 GiB, causing CUDA OOMs during warmup. Use | ||
| # 0.90 to restore about 8.6 GiB/GPU of activation/workspace headroom | ||
| # while remaining above the profiler floor. | ||
| MEM_FRACTION_STATIC=0.90 | ||
| CHUNKED_PREFILL_SIZE=32768 | ||
| CUDA_GRAPH_ARGS=(--cuda-graph-max-bs-decode 128) |
There was a problem hiding this comment.
🔴 The DP-attention branch launches sglang.launch_server with --cuda-graph-max-bs-decode (lines 153/163), a flag name that appears nowhere else in this repo — every other launcher, including the sibling MegaMoE DEP8 recipe sizing the identical 544 decode-graph batch (fixed_seq_len/dsv4_fp4_b300_sglang.sh:113), uses the plain --cuda-graph-max-bs. If SGLang's argparse rejects the -decode suffix, the server will fail to start for every dp-attn: true config (3 of the 5 search-space rows), which is exactly the MegaMoE DEP configuration this PR exists to rerun. Please confirm against the pinned SGLang image's server_args that this flag is real before merging; separately, the comment above it ("DEP8 ... serves conc up to 512") is now stale since this PR's own nvidia-master.yaml diff drops 512 from the DEP8 conc-list, leaving 196 as the new max.
Extended reasoning...
The flag. CUDA_GRAPH_ARGS=(--cuda-graph-max-bs-decode 544) (TP8, line 153) and (--cuda-graph-max-bs-decode 128) (TP4, line 163) are only reachable when DP_ATTENTION=true, which covers 3 of the 5 search-space rows in dsv4-fp4-b300-sglang-agentic-hicache (DEP4-none, DEP4-hicache, DEP8-none). A repo-wide search shows --cuda-graph-max-bs-decode exists nowhere else in InferenceX — not in any other SGLang launcher, and a git log -S pickaxe search shows this commit is the very first time the string has ever appeared in this repository's history. The strongest counter-evidence sits right next to it: benchmarks/single_node/fixed_seq_len/dsv4_fp4_b300_sglang.sh runs the same DeepSeek-V4 FP4 B300 MegaMoE DEP8 configuration (same --moe-a2a-backend megamoe, same SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK) and sizes the decode graph to the identical value, 544, but with the plain --cuda-graph-max-bs (line 113). This script's own non-DP fallback (line 191) also falls back to the plain flag. That is about as close to an apples-to-apples control as you get, and it points at a typo/transcription slip rather than an intentional, SGLang-supported decode-specific flag.\n\nWhy it matters. sglang.launch_server parses its CLI via argparse, which aborts the process with SystemExit(2) ("unrecognized arguments") on any unknown flag, before CUDA context creation or model load. If --cuda-graph-max-bs-decode isn't recognized by the pinned image (lmsysorg/sglang:nightly-dev-cu13-20260707-b4155233), every DP-attention job in this sweep — the exact B300 MegaMoE DEP recipe this PR is explicitly trying to preserve and rerun — fails immediately at startup. The PR's stated validation (bash -n, YAML parsing, load_config_files) only checks shell/YAML syntax; none of it constructs or exercises the actual sglang.launch_server argv, so this would slip through and only be caught once the GPU jobs actually run.\n\nAddressing the refutation. One verifier argued this is refuted by the PR's own evidence: the OOM analysis in the description says jobs from run 29367944489 reached CUDA warmup and died inside deep_gemm.fp8_paged_mqa_logits — which is downstream of argument parsing, so if the flag were invalid, those jobs would have died at parse time instead, before ever touching CUDA. That's a real observation, but it rests on an unverifiable assumption: that predecessor PR #2145's script used the exact same -decode spelling and that this PR's DEP4 lines are a byte-for-byte carryover. I could not find #2145 in this repository's git history (no remote is configured, and no prior commit ever contains "cuda-graph-max-bs-decode" per git log -S), and the PR description itself calls this a rebuild "on the latest main" of a PR whose diff had to be manually reconstructed (excluding B200 and changelog changes). A manual reconstruction is exactly the kind of step where a flag name could be mistyped even if the original #2145 script used the correct plain flag — we simply cannot confirm from what's in front of us that the run 29367944489 logs correspond to a config using the -decode spelling rather than the correct one. Given that ambiguity, and given that the one piece of concrete, in-repo, apples-to-apples evidence (the sibling fixed_seq_len recipe) uses the plain flag for the identical 544 value, I still think this needs the author to explicitly confirm the flag against the pinned SGLang image before merge rather than relying on an inference about an unrelated historical run.\n\nStep-by-step proof of the failure mode (if the flag is indeed invalid):\n1. A search-space entry with dp-attn: true, e.g. tp: 8, ep: 8, is scheduled — one of the 3 affected rows.\n2. The script enters the DP_ATTENTION=true branch (line ~119) and, since TP=8, sets CUDA_GRAPH_ARGS=(--cuda-graph-max-bs-decode 544) (line 153).\n3. SGLANG_CMD is assembled including "" (line ~229) and executed via "" >> "" 2>&1 &.\n4. sglang.launch_server's argparse.ArgumentParser.parse_args() encounters --cuda-graph-max-bs-decode, finds no matching add_argument, and calls parser.error(...), which prints "unrecognized arguments: --cuda-graph-max-bs-decode 544" and exits with status 2 — before any CUDA/model initialization.\n5. wait_for_server_ready polls the health port, never gets a response (the process already exited), and the job fails/hangs on the timeout instead of ever reaching the benchmark — for all 3 dp-attn rows, defeating the PR's stated purpose of rerunning exactly this B300 MegaMoE DEP configuration.\n\nFix. Confirm --cuda-graph-max-bs-decode is a recognized argument in the pinned SGLang nightly's server_args.py/launch_server before merge (e.g. via python -m sglang.launch_server --help against the actual image, or grepping the vendored SGLang source in the container). If it isn't, change both occurrences (lines 153, 163) to the plain --cuda-graph-max-bs, consistent with the sibling MegaMoE recipe and this script's own non-DP fallback. While touching this block, the comment directly above ("DEP8 (dp 8) serves conc up to 512") is also worth updating since this PR's own configs/nvidia-master.yaml diff removes 512 from the DEP8 conc-list, leaving 196 as the new max — a cosmetic follow-up, not a blocker on its own.
| agentic-coding: | ||
| - dram-utilization: 0.80 | ||
| search-space: | ||
| - { tp: 4, kv-offloading: none, conc-list: [1, 4, 8, 16, 20, 24, 32] } | ||
| - { tp: 8, kv-offloading: none, conc-list: [1, 4, 8, 16, 32, 40, 48, 52, 56, 60, 64, 72] } | ||
| - { tp: 4, ep: 4, dp-attn: true, kv-offloading: none, conc-list: [8, 16, 24, 32, 40, 64], router: { name: sglang-router, version: "0.3.2" } } | ||
| - { tp: 4, ep: 4, dp-attn: true, kv-offloading: dram, kv-offload-backend: { name: hicache }, conc-list: [32, 40, 48, 56, 64, 72, 80, 88, 96, 128], router: { name: sglang-router, version: "0.3.2" } } | ||
| - { tp: 8, ep: 8, dp-attn: true, kv-offloading: none, conc-list: [52, 72, 100, 128, 144, 196, 512], router: { name: sglang-router, version: "0.3.2" } } | ||
| - { tp: 4, kv-offloading: none, conc-list: [1, 2, 4, 8, 16] } | ||
| - { tp: 8, kv-offloading: none, conc-list: [1, 2, 4, 8, 16, 32, 40] } | ||
| - { tp: 4, ep: 4, dp-attn: true, kv-offloading: none, conc-list: [8, 16, 24, 32, 40], router: { name: sglang-router, version: "0.3.2" } } |
There was a problem hiding this comment.
🔴 This PR changes the B300 benchmark recipe (mem-fraction-static, MegaMoE DEP path, new low-latency TP path, several SGLANG_* env vars) and the corresponding search-space in configs/nvidia-master.yaml, but appends no entry to perf-changelog.yaml. Since run-sweep.yml is path-filtered on perf-changelog.yaml and process_changelog.py derives the entire sweep matrix from newly-appended changelog lines, merging as-is means the B300 rerun this PR exists to produce will never execute. Please append a perf-changelog.yaml entry keyed to dsv4-fp4-b300-sglang-agentic-hicache (config-key, description, PR link) at the end of the file.
Extended reasoning...
What the bug is: The PR's stated purpose is to "rerun only the B300 configuration" for dsv4-fp4-b300-sglang-agentic-hicache with a lowered mem-fraction-static (0.93 → 0.90) to fix an observed CUDA OOM, plus a broader recipe overhaul (MegaMoE DEP path, a new low-latency TP-only path, several new SGLANG_* env vars, and revised conc-list search-space entries). The changed-files set for this PR is exactly two files — benchmarks/single_node/agentic/dsv4_fp4_b300_sglang.sh and configs/nvidia-master.yaml. No entry is appended to perf-changelog.yaml.
The code path that triggers it: .github/workflows/run-sweep.yml gates both its push (lines 25-26) and pull_request (lines 35-36) triggers with paths: ["perf-changelog.yaml"]. Since this PR never touches that file, the entire sweep workflow (including check-changelog, the reuse-sweep gate, and the actual benchmark jobs) will not fire on this PR, and will not fire on the post-merge push to main either. Even setting aside the workflow-level path filter, the sweep's matrix is itself derived from perf-changelog.yaml: utils/process_changelog.py's get_added_lines() git-diffs only that file between base and head, and main() explicitly raises ValueError("No additions found in the changelog file.") when there are no appended lines (utils/process_changelog.py:128-129). The config-keys from each appended changelog entry are what get resolved against the master config via get_config_keys_from_master() to build the actual sweep — so an empty changelog diff means zero configs get selected, config-key resolution never runs, and the dsv4-fp4-b300-sglang-agentic-hicache search-space this PR just edited is never benchmarked.
Why existing code doesn't prevent it: There is no other trigger path. Labels like full-sweep-fail-fast only affect fail-fast behavior of matrix jobs that are already running — they don't bypass the perf-changelog.yaml path filter. validate_perf_changelog.py (or equivalent validation) does not error out when the changelog is left unchanged, so nothing blocks the merge; the sweep just silently never runs. Recent config-changing PRs in this repo (e.g. #2158/#2222, #2197, #2198) consistently append a changelog entry alongside their config edits, and the immediate predecessor to this PR (#2145) also lacks one, showing this omission isn't a one-off outlier but a real gap that AGENTS.md and the PR checklist both explicitly call out as required ("append a perf-changelog.yaml entry (required — triggers benchmarks)").
Impact: Concretely, merging this PR as-is makes it a functional no-op for its own stated purpose. The mem-fraction-static OOM fix, the MegaMoE DEP path, the new low-latency TP-only path, and the revised concurrency search-space all land on main, but none of them get exercised by CI — the exact scenario (DEP4 CUDA OOM in deep_gemm.fp8_paged_mqa_logits) that motivated this PR will not be re-validated. A maintainer or the author would need a follow-up PR just to actually trigger the benchmark.
Step-by-step proof:
git diff main...HEAD -- perf-changelog.yamlfor this PR is empty (onlydsv4_fp4_b300_sglang.shandnvidia-master.yamlare in<changed-files>).- On
pull_request, GitHub Actions evaluatesrun-sweep.yml's trigger: the event's changed-file set intersected withpaths: ["perf-changelog.yaml"]is empty, so the workflow does not run at all, regardless of labels applied. - Suppose the workflow were manually forced to run anyway (e.g., via
workflow_dispatch): the setup job callsprocess_changelog.py --base-ref ... --head-ref ..., which callsget_added_lines()— a git diff scoped toperf-changelog.yamlonly. Since no lines were added there,added_yaml.strip()is empty andmain()raisesValueError("No additions found in the changelog file."), hard-failing before any config-key resolution or sweep construction happens. - Either way, the
dsv4-fp4-b300-sglang-agentic-hicacheconfig — the one this PR just modified — never gets included in a benchmark run.
How to fix: Append a perf-changelog.yaml entry at the end of the file with config-key: dsv4-fp4-b300-sglang-agentic-hicache, a short description of the mem-fraction/MegaMoE/low-latency changes, and a link to this PR — mirroring the format used by the sibling PRs (#2158/#2222, #2197, #2198) that touched nvidia-master.yaml.
|
see unofficial run visualizer at https://inferencex.semianalysis.com/inference?unofficialRun=29434737541 |
Summary
main.mem-fraction-staticfrom0.93to0.90. In run 29367944489, the six apparently hung B300 jobs had scheduler CUDA OOMs indeep_gemm.fp8_paged_mqa_logits: only 2.9–4.8 GiB remained free for 4.2–6.1 GiB allocations. The lower fraction returns about 8.6 GiB/GPU of headroom while staying above the observed model-profiler floor.Validation
bash -n benchmarks/single_node/agentic/dsv4_fp4_b300_sglang.shconfigs/nvidia-master.yamlwith PyYAML.utils.matrix_logic.validation.load_config_files.中文说明
main重新构建分支。mem-fraction-static从0.93降至0.90。运行 29367944489 中 6 个看似卡住的 B300 任务实际在deep_gemm.fp8_paged_mqa_logits触发了调度器 CUDA OOM:当时仅剩 2.9–4.8 GiB 显存,却需要分配 4.2–6.1 GiB。降低该比例后,每张 GPU 可多预留约 8.6 GiB,同时仍高于实测模型分析器下限。验证
bash -n benchmarks/single_node/agentic/dsv4_fp4_b300_sglang.shconfigs/nvidia-master.yaml。utils.matrix_logic.validation.load_config_files加载并验证全部 147 个 master 配置。